# 设置CMake模块路径
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/modules)

# ======================== Qt Configuration ========================
macro(find_qt)
    if(vs_version STREQUAL vs2015)
        set(Qt5_DIR "C:/Qt/5.9.7/msvc2015_64/lib/cmake/Qt5")
        set(Qt5_BIN_DIR C:/Qt/5.9.7/msvc2015_64/bin)
    elseif(vs_version STREQUAL vs2019)
        set(Qt5_DIR "C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5")
        set(Qt5_BIN_DIR C:/Qt/5.15.2/msvc2019_64/bin)
    endif()

    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_AUTOUIC ON)
    find_package(Qt5 COMPONENTS Core Widgets Gui Network REQUIRED)
    message(STATUS "Qt5Core_INCLUDE_DIRS = ${Qt5Core_INCLUDE_DIRS}")
endmacro()

# ======================== Boost Configuration ========================
macro(find_boost)
    cmake_policy(SET CMP0074 NEW)
    set(Boost_USE_STATIC_RUNTIME ON)
    set(Boost_USE_STATIC_LIBS ON)
    set(Boost_NO_SYSTEM_PATHS ON)

    if(vs_version STREQUAL vs2015)  
        set(BOOST_ROOT ${CMAKE_CURRENT_LIST_DIR}/third-party/common/boost)
        set(BOOST_INCLUDEDIR ${BOOST_ROOT}/include)
        set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib64-msvc-14.0)
    elseif(vs_version STREQUAL vs2019)
        set(BOOST_ROOT ${CMAKE_CURRENT_LIST_DIR}/third-party/common_vs2019/boost)
        set(BOOST_INCLUDEDIR ${BOOST_ROOT}/include)
        set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib64-msvc-14.2)
    endif()

    find_package(Boost 1.72.0 REQUIRED COMPONENTS system thread filesystem)
    if(Boost_FOUND)
        message(STATUS "BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR}")
        message(STATUS "BOOST_LIBRARYDIR=${BOOST_LIBRARYDIR}")
        message(STATUS "Boost_VERSION=${Boost_VERSION}")
    else()
        message(FATAL_ERROR "Boost not found")
    endif()
endmacro()

# ======================== OpenCV Configuration ========================
macro(find_opencv)
    set(MY_OPENCV_DIR ${CMAKE_CURRENT_LIST_DIR}/third-party/common/opencv)
    set(MY_OPENCV_INCLUDE_DIR ${MY_OPENCV_DIR}/include)
    
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
        set(MY_OPENCV_LIBS_DIR ${MY_OPENCV_DIR}/debug/lib)
        set(MY_OPENCV_BIN_DIR ${MY_OPENCV_DIR}/debug/bin)
        set(MY_OPENCV_LIBS opencv_cored.lib opencv_highguid.lib opencv_imgcodecsd.lib opencv_imgprocd.lib)
    else()
        set(MY_OPENCV_LIBS_DIR ${MY_OPENCV_DIR}/lib)
        set(MY_OPENCV_BIN_DIR ${MY_OPENCV_DIR}/bin)
        set(MY_OPENCV_LIBS opencv_core.lib opencv_highgui.lib opencv_imgcodecs.lib opencv_imgproc.lib)
    endif()
    
    message(STATUS "MY_OPENCV_LIBS = ${MY_OPENCV_LIBS}")
    
    if(OpenCV_FOUND)
        message(STATUS "OpenCV Found: ${OpenCV_VERSION}")
    else()
        message(FATAL_ERROR "OpenCV not found")
    endif()
endmacro()

# ======================== YAML-CPP Configuration ========================
macro(find_yaml_cpp)
    set(MY_YAML_DIR ${CMAKE_CURRENT_LIST_DIR}/third-party/common/yaml-cpp)
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
        set(MY_YAML_LIB_DIR ${MY_YAML_DIR}/lib/debug)
        set(MY_YAML_BIN_DIR ${MY_YAML_DIR}/bin/debug)
    else()
        set(MY_YAML_LIB_DIR ${MY_YAML_DIR}/lib/release)
        set(MY_YAML_BIN_DIR ${MY_YAML_DIR}/bin/release)
    endif()
    
    set(MY_YAML_INCLUDE_DIR ${MY_YAML_DIR}/include)
    set(MY_YAML_LIB yaml-cpp.lib)
    
    include_directories(${MY_YAML_INCLUDE_DIR})
    link_directories(${MY_YAML_LIB_DIR})
    
    if(yaml-cpp_FOUND)
        message(STATUS "yaml-cpp Found")
    else()
        message(FATAL_ERROR "yaml-cpp not found")
    endif()
endmacro()

# ======================== CUDA Configuration ========================
macro(find_cuda)
    option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
    
    if(MY_CUDA_VERSION STREQUAL 10.2)
        set(CUDA_TOOLKIT_ROOT_DIR "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.2")
    elseif(MY_CUDA_VERSION STREQUAL 11.1)
        set(CUDA_TOOLKIT_ROOT_DIR "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.1")
    endif()
    
    set(CUDAToolkit_ROOT ${CUDA_TOOLKIT_ROOT_DIR})
    set(CMAKE_VS_PLATFORM_TOOLSET_CUDA ${MY_CUDA_VERSION})
    
    find_package(CUDAToolkit REQUIRED)
    if(CUDAToolkit_FOUND)
        message(STATUS "CUDAToolkit_VERSION: ${CUDAToolkit_VERSION}")
        message(STATUS "CUDAToolkit_BIN_DIR: ${CUDAToolkit_BIN_DIR}")
        message(STATUS "CUDAToolkit_LIBRARY_ROOT: ${CUDAToolkit_LIBRARY_ROOT}")
        
        set(MY_CUDA_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIRS})
        set(MY_CUDA_LIBRARY_DIRS ${CUDAToolkit_LIBRARY_DIRS})
        set(MY_CUDA_LIBRARIES cudart)
        
        # NVCC flags
        set(CUDA_NVCC_FLAGS -gencode arch=compute_52,compute_60,compute_61,compute_70,compute_75,code=sm_52,sm_60,sm_61,sm_70,sm_75;-G;-g)
        if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
            set(CMAKE_CUDA_ARCHITECTURES 52 60 61 70 75)
        endif()
    else()
        message(FATAL_ERROR "CUDA not found")
    endif()
endmacro()

# ======================== TensorRT Configuration ========================
macro(find_tensorrt)
    if(MY_CUDA_VERSION STREQUAL 10.2)
        set(MY_TRT_DIR ${CMAKE_CURRENT_LIST_DIR}/third-party/cuda10-cudnn8-rt-7/tensorrt/TensorRT-7.2.2.3)
    elseif(MY_CUDA_VERSION STREQUAL 11.1)
        if(MY_TRT_VERSION STREQUAL 7)
            set(MY_TRT_DIR ${CMAKE_CURRENT_LIST_DIR}/third-party/cuda11-cudnn8-rt-7/tensorrt)
        elseif(MY_TRT_VERSION STREQUAL 8)
            set(MY_TRT_DIR ${CMAKE_CURRENT_LIST_DIR}/third-party/cuda11-cudnn8-rt-8/tensorrt)
        endif()
    endif()
    
    set(MY_TRT_INCLUDE_DIR ${MY_TRT_DIR}/include)
    set(MY_TRT_LIB_DIR ${MY_TRT_DIR}/lib)
    set(MY_TRT_BIN_DIR ${MY_TRT_DIR}/lib)
    set(MY_TRT_LIBS nvinfer nvonnxparser)
    
    include_directories(${MY_TRT_INCLUDE_DIR})
    link_directories(${MY_TRT_LIB_DIR})
    
    message(STATUS "MY_TRT_DIR: ${MY_TRT_DIR}")
    
    if(TensorRT_FOUND)
        message(STATUS "TensorRT Found: ${TensorRT_VERSION}")
    else()
        message(FATAL_ERROR "TensorRT not found")
    endif()
endmacro()

# 所有依赖包的查找
macro(find_all_packages)
    find_qt()
    find_opencv()
    find_boost()
    find_cuda()
    find_tensorrt()
    find_yaml_cpp()
endmacro()

# 设置所有包的包含目录
macro(set_all_includes target)
    target_include_directories(${target} PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${CMAKE_CURRENT_BINARY_DIR}
        ${Qt5Core_INCLUDE_DIRS}
        ${MY_OPENCV_INCLUDE_DIR}
        ${BOOST_INCLUDEDIR}
        ${MY_CUDA_INCLUDE_DIRS}
        ${MY_TRT_INCLUDE_DIR}
        ${MY_YAML_INCLUDE_DIR}
    )
endmacro()

# 链接所有依赖库
macro(link_all_libraries target)
    target_link_libraries(${target} PRIVATE
        Qt5::Core
        Qt5::Widgets
        Qt5::Gui
        Qt5::Network
        ${MY_OPENCV_LIBS}
        ${Boost_LIBRARIES}
        ${MY_YAML_LIB}
        ${MY_CUDA_LIBRARIES}
        ${MY_TRT_LIBS}
    )
endmacro() 